File indexing completed on 2024-04-28 16:08:34

0001 /***************************************************************************
0002  *   Copyright (C) 2017 by Linuxstopmotion contributors;                   *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 
0021 #include "stringwriter.h"
0022 
0023 #include <string.h>
0024 
0025 StringWriter::StringWriter() : startOfLine(true) {
0026 }
0027 
0028 const char* StringWriter::result() const {
0029     return buffer.c_str();
0030 }
0031 
0032 void StringWriter::reset() {
0033     startOfLine = true;
0034     buffer.clear();
0035 }
0036 
0037 int32_t StringWriter::length() const {
0038     return buffer.length();
0039 }
0040 
0041 void StringWriter::writeChar(char c) {
0042     buffer.append(1, c);
0043 }
0044 
0045 void StringWriter::beginArgument() {
0046     if (!startOfLine) {
0047         writeChar(' ');
0048     }
0049     startOfLine = false;
0050 }
0051 
0052 void StringWriter::writeDigit(int32_t d) {
0053     writeChar(static_cast<char>('0' + d));
0054 }
0055 
0056 void StringWriter::writeString(const char* s) {
0057     beginArgument();
0058     writeChar('"');
0059     bool allowDigits = true;
0060     while (*s) {
0061         unsigned char c = *reinterpret_cast<const unsigned char*>(s);
0062         ++s;
0063         if (strchr("\r\n\\\"", c)) {
0064             writeChar('\\');
0065             if (c == '\r')
0066                 writeChar('r');
0067             else if (c == '\n')
0068                 writeChar('n');
0069             else
0070                 writeChar(c);
0071             allowDigits = true;
0072         } else if ((32 <= c && c < '0') || ('9' < c && c < 128)) {
0073             writeChar(c);
0074             allowDigits = true;
0075         } else if (allowDigits && '0' <= c && c <= '9') {
0076             writeChar(c);
0077         } else {
0078             writeChar('\\');
0079             bool started = false;
0080             int32_t power = 64;
0081             int32_t ci = c;
0082             while (0 < power) {
0083                 int32_t digit = ci / power;
0084                 digit %= 8;
0085                 power /= 8;
0086                 if (digit != 0)
0087                     started = true;
0088                 if (started || power == 1)
0089                     writeDigit(digit);
0090             }
0091             allowDigits = false;
0092         }
0093     }
0094     writeChar('"');
0095 }
0096 
0097 void StringWriter::writeInteger(int32_t n) {
0098     beginArgument();
0099     if (n < 0) {
0100         writeChar('-');
0101         n = -n;
0102     }
0103     int power = 1;
0104     int nOver10 = n / 10;
0105     while (power <= nOver10) {
0106         power *= 10;
0107     }
0108     while (power) {
0109         int32_t digit = n / power;
0110         n %= power;
0111         power /= 10;
0112         writeChar('0' + digit);
0113     }
0114 }
0115 
0116 void StringWriter::writeIdentifier(const char* id) {
0117     beginArgument();
0118     while (*id) {
0119         writeChar(*id);
0120         ++id;
0121     }
0122 }