package yaffs2.utils;
import yaffs2.port.*;
import yaffs2.utils.factory.PrimitiveWrapper;
/**
* Note that these methods are neither semantically nor syntactically equivalent to their
* archetypes.
* Rather, they should fit to the porting style.
*
*/
public class Unix
{
public static void memset(byte[] s, int sIndex, byte c, int n)
{
for (int i = sIndex; i < sIndex + n; i++)
s[i] = c;
}
public static void memset(yaffs_Tnode s)
{
for (int i = 0; i < s.internal.length; i++)
s.internal[i] = null;
memset((PartiallySerializableObject)s,(byte)0);
}
public static void memset(list_head s)
{
s.next = null;
s.prev = null;
}
public static void memset(yaffsfs_Handle s)
{
s.inUse = false;
s.readOnly = false;
s.append = false;
s.exclusive = false;
s.position = 0;
s.obj = null;
}
public static void memset(yaffsfs_DirectorySearchContext s)
{
s.magic = 0;
memset(s.de);
memset(s.name, 0, (byte)0, s.name.length);
s.nameIndex = 0;
s.dirObj = null;
s.nextReturn = null;
s.offset = 0;
memset(s.others);
}
public static void memset(yaffs_dirent s)
{
s.d_ino = 0;
s.d_off = 0;
// s.d_reclen = 0;
memset(s.d_name, 0, (byte)0, s.d_name.length);
s.d_nameIndex = 0;
s.d_dont_use = null;
}
public static void memset(yaffs_ExtendedTags s)
{
s.validMarker0 = 0;
s.chunkUsed = false;
s.objectId = 0;
s.chunkId = 0;
s.byteCount = 0;
s.eccResult = 0;
s.blockBad = false;
s.chunkDeleted = false;
s.serialNumber = 0;
s.sequenceNumber = 0;
s.extraHeaderInfoAvailable = false;
s.extraParentObjectId = 0;
s.extraIsShrinkHeader = false;
s.extraShadows = false;
s.extraObjectType = 0;
s.extraFileLength = 0;
s.extraEquivalentObjectId = 0;
s.validMarker1 = 0;
}
public static void memset(yaffs_Object s)
{
s.sub.deleted = false; /* This should only apply to unlinked files. */
s.sub.softDeleted = false; /* it has also been soft deleted */
s.sub.unlinked = false; /* An unlinked file. The file should be in the unlinked directory.*/
s.sub.fake = false; /* A fake object has no presence on NAND. */
s.renameAllowed = false; /* Some objects are not allowed to be renamed. */
s.unlinkAllowed = false;
s.dirty = false; /* the object needs to be written to flash */
s.valid = false; /* When the file system is being loaded up, this
* object might be created before the data
* is available (ie. file data records appear before the header).
*/
s.lazyLoaded = false; /* This object has been lazy loaded and is missing some detail */
s.deferedFree = false; /* For Linux kernel. Object is removed from NAND, but is
* still in the inode cache. Free of object is defered.
* until the inode is released.
*/
s.serial = 0; /* serial number of chunk in NAND. Cached here */
s.sum = 0; /* sum of the name to speed searching */
s.myDev = null; /* The device I'm on */
memset(s.hashLink);
memset(s.hardLinks);
s.parent = null;
memset(s.siblings);
s.chunkId = 0;
s.nDataChunks = 0;
s.objectId = 0;
s.yst_mode = 0;
//#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
for (int i = 0; i < s.shortName.length; i++)
s.shortName[i] = 0;
//#endif
s.inUse = 0;
s.yst_uid = 0;
s.yst_gid = 0;
s.yst_atime = 0;
s.yst_mtime = 0;
s.yst_ctime = 0;
s.yst_rdev = 0;
s.variantType = 0;
memset(s.variant);
}
public static void memset(yaffs_ObjectVariant s)
{
memset(s.fileVariant);
memset(s.directoryVariant);
memset(s.symLinkVariant);
memset(s.hardLinkVariant);
}
public static void memset(yaffs_FileStructure s)
{
s.fileSize = 0;
s.scannedFileSize = 0;
s.shrinkSize = 0;
s.topLevel = 0;
s.top = null;
}
public static void memset(yaffs_DirectoryStructure s)
{
memset(s.children);
}
public static void memset(yaffs_SymLinkStructure s)
{
s.alias = null;
s.aliasIndex = 0;
}
public static void memset(yaffs_HardLinkStructure s)
{
s.equivalentObject = null;
s.equivalentObjectId = 0;
}
public static void memset(SerializableObject s, byte c)
{
memset(s.serialized, s.offset, c, s.getSerializedLength());
}
public static void memset(SerializableObject[] s, byte c)
{
for (int i = 0; i < s.length; i++)
memset(s[i], c);
}
public static void memcpy(yaffs_Tnode dest, yaffs_Tnode src)
{
for (int i = 0; i < dest.internal.length; i++)
dest.internal[i] = src.internal[i];
memcpy((PartiallySerializableObject)dest,(PartiallySerializableObject)src);
}
public static void memcpy(byte[] dest, int destIndex, byte[] src, int srcIndex, int num)
{
System.arraycopy(src, srcIndex, dest, destIndex, num);
}
/**
* As long as a class only contains other SerializableObjects and Primitives,
* this works.
*
*/
public static void memcpy(SerializableObject dest, SerializableObject src)
{
// assert dest.getClass().equals(src.getClass());
System.arraycopy(src.serialized, src.offset,
dest.serialized, dest.offset, dest.getSerializedLength());
}
public static int memcmp(byte[] s1, int s1Index, byte[] s2, int s2Index, int n) {
for (int i = 0; i < n; i++) {
int compare;
compare = s1[s1Index+i] - s2[s2Index+i];
if (compare != 0) {
return compare;
}
}
return 0;
}
public static int memcmp(SerializableObject s1, SerializableObject s2)
{
// assert s1.getClass().equals(s2.getClass());
// assert s1.getSerializedLength() == s2.getSerializedLength();
return memcmp(s1.serialized, s1.offset, s2.serialized, s2.offset, s1.getSerializedLength());
}
public static int strcmp(byte[] s1, int s1Index, byte[] s2, int s2Index)
{
int i = 0;
while (s1[s1Index+i] == s2[s2Index+i] && s1[s1Index+i] != 0)
i++;
return s1[s1Index+i]-s2[s2Index+i];
}
public static int strncmp(byte[] s1, int s1Index, byte[] s2, int s2Index, int n)
{
int i = 0;
while (s1[s1Index+i] == s2[s2Index+i] && s1[s1Index+i] != 0)
{
if (i == n-1)
return 0;
i++;
}
return s1[s1Index+i]-s2[s2Index+i];
}
public static void strcpy(byte[] a, int aIndex, byte[] b, int bIndex)
{
int i = 0;
do
{
a[aIndex+i] = b[bIndex+i];
} while (b[bIndex+(i++)] != 0);
}
public static void strncpy(byte[] a, int aIndex, byte[] b, int bIndex, int c)
{
boolean nullEncountered = false;
for (int i = 0; i < c; i++)
{
if (!nullEncountered)
{
nullEncountered = b[bIndex+i] == 0;
a[aIndex+i] = b[bIndex+i];
}
else
{
a[aIndex+i] = 0;
}
}
}
public static int strlen(byte[] s, int sIndex)
{
int i = 0;
// this is not a bug imo, this should only be called on zero-terminated strings
while (s[sIndex+i] != 0)
++i;
return i;
}
public static PrimitiveWrapper[] xprintfArgs = new PrimitiveWrapper[9];
// PORT
static byte[] _STATIC_LOCAL_printf_buffer = new byte[200];
static final int _STATIC_LOCAL_printf_bufferIndex = 0;
// XXX only for emulation
static int debugLines = 0;
public static void printf(String format, PrimitiveWrapper arg0)
{
xprintfArgs[0] = arg0;
// xprintfArgs[1] = arg1;
//// xprintfArgs[2] = arg2;
////// xprintfArgs[3] = arg3;
//////// xprintfArgs[4] = arg4;
////////// xprintfArgs[5] = arg5;
printf(format);
}
public static void printf(String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
// xprintfArgs[2] = arg2;
//// xprintfArgs[3] = arg3;
////// xprintfArgs[4] = arg4;
//////// xprintfArgs[5] = arg5;
printf(format);
}
public static void printf(String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
// xprintfArgs[3] = arg3;
//// xprintfArgs[4] = arg4;
////// xprintfArgs[5] = arg5;
printf(format);
}
public static void printf(String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2, PrimitiveWrapper arg3)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
xprintfArgs[3] = arg3;
// xprintfArgs[4] = arg4;
//// xprintfArgs[5] = arg5;
printf(format);
}
public static void printf(String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2, PrimitiveWrapper arg3, PrimitiveWrapper arg4)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
xprintfArgs[3] = arg3;
xprintfArgs[4] = arg4;
// xprintfArgs[5] = arg5;
printf(format);
}
public static void printf(String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2, PrimitiveWrapper arg3, PrimitiveWrapper arg4, PrimitiveWrapper arg5)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
xprintfArgs[3] = arg3;
xprintfArgs[4] = arg4;
xprintfArgs[5] = arg5;
printf(format);
}
public static void sprintf(byte[] s, int sIndex, String format, PrimitiveWrapper arg0)
{
xprintfArgs[0] = arg0;
sprintf(s, sIndex, format);
}
public static void sprintf(byte[] s, int sIndex, String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
sprintf(s, sIndex, format);
}
public static void sprintf(byte[] s, int sIndex, String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
sprintf(s, sIndex, format);
}
public static void sprintf(byte[] s, int sIndex, String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2, PrimitiveWrapper arg3)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
xprintfArgs[3] = arg3;
sprintf(s, sIndex, format);
}
public static void sprintf(byte[] s, int sIndex, String format, PrimitiveWrapper arg0, PrimitiveWrapper arg1, PrimitiveWrapper arg2, PrimitiveWrapper arg3, PrimitiveWrapper arg4)
{
xprintfArgs[0] = arg0;
xprintfArgs[1] = arg1;
xprintfArgs[2] = arg2;
xprintfArgs[3] = arg3;
xprintfArgs[4] = arg4;
sprintf(s, sIndex, format);
}
/**
* Args must be written to printfBuffer.
* @param format
* @param args
*/
public static void printf(String format)
{
int len = sprintf(_STATIC_LOCAL_printf_buffer, _STATIC_LOCAL_printf_bufferIndex, format);
try
{
Globals.logStream.write(_STATIC_LOCAL_printf_buffer,
_STATIC_LOCAL_printf_bufferIndex, len);
}
catch(Exception e)
{
throw new UnexpectedException();
}
// String buffer = yaffs2.utils.emulation.Utils.byteArrayToString(
// _STATIC_LOCAL_printf_buffer, _STATIC_LOCAL_printf_bufferIndex);
// Globals.logStream.print(buffer);
for (int i = 0; i < len; i++)
{
if (_STATIC_LOCAL_printf_buffer[_STATIC_LOCAL_printf_bufferIndex+i] == '\n')
debugLines++;
}
int foo = 0; // use this statement to break when trace line #debugLines is written
}
// XXX only for emulation
/**
* @return Upon successful completion, the sprintf() function shall return the number of bytes written to s, excluding the terminating null byte.
*/
// XXX overflow still possible in format parsing code
/**
* Args must be written to printfBuffer.
*/
public static int sprintf(byte[] s, int sIndex, String format)
{
int formatIndex = 0;
int argsIndex = 0;
final int formatLength = format.length();
final int sLength = s.length;
int sOffset = sIndex;
char c;
while (formatIndex < formatLength && sOffset < sLength)
{
if ((c = format.charAt(formatIndex)) == '%')
{
char formatChar = format.charAt(++formatIndex);
boolean padWithZeroes = false;
int width = 0;
if (formatChar == '0') // pad with leading zeros
{
padWithZeroes = true;
formatChar = format.charAt(++formatIndex);
}
// PORT bad bad HACK
if (formatChar >= '1' && formatChar <= '9')
{
width = formatChar - '0';
formatChar = format.charAt(++formatIndex);
}
// XXX make sure of no overflows && sOffset reaches sLength
switch (formatChar)
{
case 'd': // integer
case 'i':
{
int val = xprintfArgs[argsIndex]._int;
if (val < 0)
{
s[sOffset++] = '-';
}
int buf;
buf = Math.abs(val);
int digits = 1;
while (buf >= 10)
{
digits++;
buf /= 10;
}
for (int i= 0; i < width-digits; i++)
{
s[sOffset++] = padWithZeroes ? (byte)'0' : (byte)' ';
}
buf = Math.abs(val);
for (int i = 0; i < digits; i++)
{
s[sOffset + (digits-1-i)] = (byte)('0' + (buf % 10));
buf /= 10;
}
sOffset += digits;
break;
}
case 'x': // hex // XXX
case 'X':
{
int val = xprintfArgs[argsIndex]._int;
int buf;
buf = val;
int digits = 1;
while (Math.abs(buf) >= 16)
{
digits++;
buf /= 16;
}
for (int i= 0; i < width-digits; i++)
{
s[sOffset++] = padWithZeroes ? (byte)'0' : (byte)' ';
}
buf = val;
for (int i = 0; i < digits; i++)
{
int charValue = buf % 16;
s[sOffset + (digits-1-i)] = (byte)((charValue >= 10 ? 'a'-10 : '0') + charValue);
buf /= 16;
}
sOffset += digits;
break;
}
case 'b': // boolean
{
s[sOffset++] = xprintfArgs[argsIndex]._boolean ? (byte)'1' : (byte)'0';
break;
}
case 's': // char string
{
String str = xprintfArgs[argsIndex]._String;
int len = str.length();
for (int i = 0; i < len; i++)
s[sOffset++] = (byte)str.charAt(i);
break;
}
case 'a': // PORT byte[] array, int offset
{
byte[] array = xprintfArgs[argsIndex]._byteArray;
int offset = xprintfArgs[argsIndex+1]._int;
int len = strlen(array, offset);
// trim to avoid buffer overflow
len = Math.min(len, sLength-sOffset);
System.arraycopy(array, offset, s, sOffset, len);
sOffset += len;
argsIndex++; // 2 args consumed
break;
}
case '%':
{
s[sOffset++] = (byte)'%';
argsIndex--; // no arg consumed
break;
}
default:
// assert false;
}
argsIndex++;
}
else
s[sOffset++] = (byte)c;
formatIndex++;
}
// assert sOffset < sLength-1;
if (!(sOffset <= sLength-1))
sOffset = sLength-1;
s[sOffset] = 0;
return sOffset-sIndex;
}
public static final int _IFMT = 0170000; /* type of file */
public static final int _IFCHR = 0020000; /* character special */
public static final int _IFBLK = 0060000; /* block special */
public static final int _IFSOCK = 0140000; /* socket */
public static final int _IFIFO = 0010000; /* fifo */
public static boolean S_ISCHR(int m)
{
return (((m)&_IFMT) == _IFCHR);
}
public static boolean S_ISBLK(int m)
{
return (((m)&_IFMT) == _IFBLK);
}
public static boolean S_ISFIFO(int m)
{
return (((m)&_IFMT) == _IFIFO);
}
public static boolean S_ISSOCK(int m)
{
return (((m)&_IFMT) == _IFSOCK);
}
public static final int S_IFDIR = 0040000;
}