예제 #1
0
ECode UriCodec::Decode(
    /* [in] */ const String& s,
    /* [in] */ Boolean convertPlus,
    /* [in] */ ICharset* charset,
    /* [in] */ Boolean throwOnFailure,
    /* [out] */ String* decodedString)
{
    VALIDATE_NOT_NULL(decodedString);
    if (s.IndexOf('%') == -1 && (!convertPlus || s.IndexOf('+') == -1)) {
        *decodedString = s;
        return NOERROR;
    }

    StringBuilder result(s.GetByteLength());
    AutoPtr<IByteArrayOutputStream> out;
    CByteArrayOutputStream::New((IByteArrayOutputStream**)&out);
    IOutputStream* os = IOutputStream::Probe(out);
    AutoPtr<ArrayOf<Char32> > char32Array = s.GetChars();
    for (Int32 i = 0; i < s.GetLength();) {
        Char32 c = (*char32Array)[i];
        if (c == '%') {
            do {
                Int32 d1, d2;
                if (i + 2 < s.GetLength()
                        && (d1 = HexToInt((*char32Array)[i + 1])) != -1
                        && (d2 = HexToInt((*char32Array)[i + 2])) != -1) {
                    os->Write((Byte) ((d1 << 4) + d2));
                }
                else if (throwOnFailure) {
                    return E_ILLEGAL_ARGUMENT_EXCEPTION;
                }
                else {
                    // TODO: unicode escape
                    const char* chars = "\ufffd";
                    AutoPtr<ArrayOf<Byte> > replacement = GetBytes(chars, charset);
                    os->Write(replacement, 0, replacement->GetLength());
                }
                i += 3;
            } while (i < s.GetLength() && (*char32Array)[i] == '%');

            AutoPtr<ArrayOf<Byte> > bytes;
            out->ToByteArray((ArrayOf<Byte>**)&bytes);
            //result.append(new String(out.toByteArray(), charset);
            result.Append(String((char*)bytes->GetPayload()));
            out->Reset();
        }
        else {
            if (convertPlus && c == '+') {
                c = ' ';
            }
            result.AppendChar(c);
            i++;
        }
    }
    *decodedString = result.ToString();
    return NOERROR;
}
예제 #2
0
Boolean FileUtils::CopyToFile(
    /* [in] */ IInputStream* inputStream,
    /* [in] */ IFile* destFile)
{
    if (inputStream == NULL || destFile == NULL) {
        return FALSE;
    }

    Boolean result = FALSE;

    Boolean temp;
    destFile->Exists(&temp);
    if (temp) {
        destFile->Delete(&temp);
    }

    AutoPtr<IFileDescriptor> fd;
    AutoPtr<ArrayOf<Byte> > buffer;
    Int32 bytesRead;

    IOutputStream* os;
    AutoPtr<IFileOutputStream> out;
    ECode ec = CFileOutputStream::New(destFile, (IFileOutputStream**)&out);
    FAIL_GOTO(ec, _EXIT_);

    os = IOutputStream::Probe(out);
    buffer = ArrayOf<Byte>::Alloc(4096);
    while (inputStream->Read(buffer, &bytesRead), bytesRead >= 0) {
        os->Write(buffer, 0, bytesRead);
    }

    IFlushable::Probe(out)->Flush();
    out->GetFD((IFileDescriptor**)&fd);
    fd->Sync();

    result = TRUE;

_EXIT_:
    if (out) {
        ICloseable::Probe(out)->Close();
    }

    return result;
}
예제 #3
0
ECode FileUtils::ReadTextFile(
    /* [in] */ IFile* file,
    /* [in] */ Int32 max,
    /* [in] */ const String& ellipsis,
    /* [out] */ String* result)
{
    VALIDATE_NOT_NULL(result);
    *result = String("");
    VALIDATE_NOT_NULL(file);

    AutoPtr<IInputStream> input;
    AutoPtr<IBufferedInputStream> bis;
    Int64 size;
    Int32 length;
    AutoPtr<ArrayOf<Byte> > data, last, tmp;
    Boolean rolled = FALSE;
    AutoPtr<IByteArrayOutputStream> contents;
    IInputStream* is;
    IOutputStream* os;

    ECode ec = CFileInputStream::New(file, (IInputStream**)&input);
    FAIL_GOTO(ec, _EXIT_);

    // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
    // input stream, bytes read not equal to buffer size is not necessarily the correct
    // indication for EOF; but it is true for BufferedInputStream due to its implementation.
    ec = CBufferedInputStream::New(input, (IBufferedInputStream**)&bis);
    FAIL_GOTO(ec, _EXIT_);

    is = IInputStream::Probe(bis);
    file->GetLength(&size);
    if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
        if (size > 0 && (max == 0 || size < max)) max = (Int32) size;
        data = ArrayOf<Byte>::Alloc(max + 1);
        is->Read(data, &length);
        if (length <= 0) {
            *result = String("");
        }
        else if (length <= max) {
            *result = String((const char *)(data->GetPayload()), length);
        }
        else if (ellipsis.IsNull()) {
            *result = String((const char *)(data->GetPayload()), max);
        }
        else {
            *result = String((const char *)(data->GetPayload()), max);
            *result += ellipsis;
        }
    }
    else if (max < 0) {  // "tail" mode: keep the last N
        do {
            if (last != NULL) rolled = true;
            tmp = last; last = data; data = tmp;
            if (data == NULL) data = ArrayOf<Byte>::Alloc(-max);
            is->Read(data, &length);
        } while (length == data->GetLength());

        if (last == NULL && length <= 0) {
            *result = String("");
            goto _EXIT_;
        }
        if (last == NULL) {
            *result = String((const char *)(data->GetPayload()), length);
            goto _EXIT_;
        }

        if (length > 0) {
            rolled = true;
            last->Copy(length, last, 0, last->GetLength() - length);
            last->Copy(last->GetLength() - length, data, 0, length);
//            System.arraycopy(last, length, last, 0, last.length - length);
//            System.arraycopy(data, 0, last, last.length - len, length);
        }

        if (ellipsis == NULL || !rolled) {
            *result = String((const char *)(last->GetPayload()), last->GetLength());
        }
        else {
            *result =  ellipsis;
            *result += String((const char *)(last->GetPayload()), last->GetLength());
        }
    }
    else {  // "cat" mode: size unknown, read it all in streaming fashion
        CByteArrayOutputStream::New((IByteArrayOutputStream**)&contents);
        os = IOutputStream::Probe(contents);
        data = ArrayOf<Byte>::Alloc(1024);
        do {
            is->Read(data, &length);
            if (length > 0) os->Write(data, 0, length);
        } while (length == data->GetLength());

        contents->ToString(result);
    }

_EXIT_:
    if (bis) ICloseable::Probe(bis)->Close();
    if (input) ICloseable::Probe(input)->Close();

    return ec;
}