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; }
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; }
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; }