ECode FileUtils::ChecksumCrc32( /* [in] */ IFile* file, /* [out] */ Int64* summer) { VALIDATE_NOT_NULL(file); VALIDATE_NOT_NULL(summer); *summer = 0; AutoPtr<ArrayOf<Byte> > buf; Int32 length; AutoPtr<ICRC32> checkSummer; CCRC32::New((ICRC32**)&checkSummer); AutoPtr<IFileInputStream> input; CFileInputStream::New(file, (IFileInputStream**)&input); IInputStream* is; AutoPtr<ICheckedInputStream> cis; ECode ec = CCheckedInputStream::New( IInputStream::Probe(input), IChecksum::Probe(checkSummer), (ICheckedInputStream**)&cis); FAIL_GOTO(ec, _EXIT_); is = IInputStream::Probe(cis); buf = ArrayOf<Byte>::Alloc(128); while(is->Read(buf, &length), length >= 0) { // Just read for checksum to get calculated. } IChecksum::Probe(checkSummer)->GetValue(summer); _EXIT_: if (cis != NULL) { ICloseable::Probe(cis)->Close(); } return ec; }
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; }